from tensorflow.keras.callbacks import Callback


class AccuracyCallback(Callback):
    def __init__(self,save_name,accuracy_fuc,accuracy_data,print_func=None):
        self.best_val_acc = 0.
        self.savename = save_name
        self.accuracy_fuc = accuracy_fuc
        self.accuracy_data = accuracy_data
        self.print_func = print_func

    def on_epoch_end(self, epoch, logs=None):
        val_acc = self.accuracy_fuc(self.accuracy_data,self.model)
        if val_acc > self.best_val_acc:
            self.best_val_acc = val_acc
            self.model.save(self.savename)
        print(
            u'val_acc: %.5f, best_val_acc: %.5f\n' %
            (val_acc, self.best_val_acc)
        )

        if self.print_func != None:
            self.print_func()


class LossSaveCallback(Callback):
    def __init__(self,save_name,print_func=None):
        self.lowest = 1e10
        self.savename = save_name
        self.print_func = print_func

    def on_epoch_end(self, epoch, logs=None):

        if logs['loss'] <= self.lowest:
            self.lowest = logs['loss']
            self.model.save(self.savename)
        print(
            u'loss: %.5f, best_loss: %.5f\n' %
            (logs['loss'], self.lowest)
        )

        if self.print_func != None:
            self.print_func()